Add new format "ggv_log". This format supports binary tracklogs used by EADS Geogrid...
authoroliskoli <oliskoli>
Mon, 26 Mar 2007 22:23:58 +0000 (22:23 +0000)
committeroliskoli <oliskoli>
Mon, 26 Mar 2007 22:23:58 +0000 (22:23 +0000)
Makefile.in
ggv_log.c [new file with mode: 0644]
reference/track/ggv_log-sample.log [new file with mode: 0644]
testo
vecs.c

index 835e7bdb89367b43a3d85b4477c95e390d431a2b..a086072bcbadc51eb4c07e156f8d3aa911f48622 100644 (file)
@@ -54,7 +54,8 @@ FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o garmin_tables.o \
        tef_xml.o maggeo.o pathaway.o vitosmt.o gdb.o bcr.o coto.o \
        ignrando.o stmwpp.o msroute.o cst.o nmn4.o mag_pdb.o compegps.o \
        yahoo.o unicsv.o wfff_xml.o garmin_txt.o axim_gpb.o gpssim.o \
-       wbt-200.o stmsdf.o gtrnctr.o dmtlog.o raymarine.o alan.o vitovtt.o
+       wbt-200.o stmsdf.o gtrnctr.o dmtlog.o raymarine.o alan.o vitovtt.o \
+       ggv_log.o
 
 FILTERS=position.o radius.o duplicate.o arcdist.o polygon.o smplrout.o \
        reverse_route.o sort.o stackfilter.o trackfilter.o discard.o \
@@ -443,6 +444,8 @@ geoniche.o: geoniche.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \
   jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
   jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
   jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h garmin_tables.h
+ggv_log.o: ggv_log.c defs.h config.h queue.h gbtypes.h gbfile.h \
+  jeeps/gpsmath.h
 globals.o: globals.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \
   zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h gbversion.h
 glogbook.o: glogbook.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \
@@ -664,7 +667,7 @@ vitosmt.o: vitosmt.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \
 vmem.o: vmem.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \
   gbfile.h cet.h cet_util.h inifile.h
 waypt.o: waypt.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h
+  zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h grtcirc.h
 wbt-200.o: wbt-200.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \
   zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h gbser.h grtcirc.h
 wfff_xml.o: wfff_xml.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \
diff --git a/ggv_log.c b/ggv_log.c
new file mode 100644 (file)
index 0000000..dbb1454
--- /dev/null
+++ b/ggv_log.c
@@ -0,0 +1,276 @@
+/*
+
+    Support for "GeoGrid Viewer" binary tracklogs (*.log)
+
+    Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include <ctype.h>
+#include <time.h>
+
+#include "defs.h"
+#include "grtcirc.h"
+#include "jeeps/gpsmath.h"
+
+#define MYNAME "ggv_log"
+
+static gbfile *fin, *fout;
+static int ggv_log_ver;
+
+static
+arglist_t ggv_log_args[] = {
+       ARG_TERMINATOR
+};
+
+/*******************************************************************************
+* %%%        global callbacks called by gpsbabel main process              %%% *
+*******************************************************************************/
+
+static void
+ggv_log_rd_init(const char *fname)
+{
+       static char magic[32];
+       int len = 0;
+
+       fin = gbfopen(fname, "rb", MYNAME);
+
+       for (;;) {
+               int cin;
+               
+               cin = gbfgetc(fin);
+               if (cin < 0) break;
+
+               magic[len++] = cin;
+               
+               if (cin == '\0') {
+                       double ver = 0;
+                       char *sver;
+                       if (strncmp(magic, "DOMGVGPS Logfile V", 18) != 0) break;
+
+                       sver = &magic[18];
+                       sscanf(sver, "%lf:", &ver);
+                       ggv_log_ver = ver * 10;
+                       if ((ggv_log_ver == 10) || (ggv_log_ver == 25)) return; /* header accepted */
+
+                       fatal(MYNAME ": Sorry, unsupported version (%s)!\n", sver);
+               }
+               else if (len == sizeof(magic))
+                       break;
+       }
+       fatal(MYNAME ": Invalid header. Probably no " MYNAME " file!\n");
+}
+
+static void 
+ggv_log_rd_deinit(void)
+{
+       gbfclose(fin);
+}
+
+static void
+ggv_log_read(void)
+{
+       signed char *buf;
+       int bufsz = 0, len;
+       route_head *trk = NULL;
+
+       switch(ggv_log_ver) {
+               case 10: bufsz = 0x2A; break;
+               case 25: bufsz = 0x6F; break;
+       }
+       
+       buf = xmalloc(bufsz);
+       
+       while ((len = gbfread(buf, 1, bufsz, fin))) {
+               int deg, min;
+               double xlat, xlon;
+               float sec;
+               struct tm tm;
+               waypoint *wpt;
+               
+               if (len != bufsz) break;
+               
+               if (trk == NULL) {
+                       trk = route_head_alloc();
+                       track_add_head(trk);
+               }
+
+               memset(&tm, 0, sizeof(tm));
+
+               wpt = waypt_new();
+
+               deg = (gbint16) le_read16(&buf[0]);
+               min = le_read16(&buf[2]);
+               sec = le_read_float(&buf[4]);
+               xlat = (double)deg + ((double)min / (double)60) + (sec / (double)3600.0);
+               wpt->latitude = xlat;
+                       
+               deg = (gbint16) le_read16(&buf[8]);
+               min = le_read16(&buf[10]);
+               sec = le_read_float(&buf[12]);
+               xlon = (double)deg + ((double)min / (double)60) + (sec / (double)3600.0);
+               wpt->longitude = xlon;
+               
+               wpt->course = le_read16(&buf[16 + 0]);
+               
+               if (ggv_log_ver == 10) {
+                       double secs;
+                       
+                       wpt->altitude = le_read16(&buf[16 +  2]);
+                       wpt->speed =    le_read16(&buf[16 +  4]);
+                       tm.tm_year =    le_read16(&buf[16 +  8]);
+                       tm.tm_mon =     le_read16(&buf[16 + 10]);
+                       tm.tm_mday =    le_read16(&buf[16 + 12]);
+                       tm.tm_hour =    le_read16(&buf[16 + 14]);
+                       tm.tm_min =     le_read16(&buf[16 + 16]);
+                       secs =          le_read_double(&buf[16 + 18]);
+                       tm.tm_sec = (int)secs;
+                       wpt->microseconds = (secs - tm.tm_sec) * 1000000;
+               }
+               else {
+                       wpt->altitude = le_read16(&buf[16 + 4]);
+                       wpt->sat = (unsigned char)buf[16 + 14];
+                       
+                       /* other probably valid double values at offset:
+                       
+                       22: 0.0 - 20.0
+                       43: 0.0 - 59.0
+                       51: -1.0
+                       61: -1.0
+                       79: .. - 20.0 ? speed over ground ? (++)
+                       87: ? course ?
+                       95: 0.0 - 3.1 (++)
+                       103: -1
+                       
+                       */
+               }
+
+               if (wpt->altitude == 0)
+                       wpt->altitude = unknown_alt;
+
+               if (tm.tm_year >= 1900) {
+                       tm.tm_year -= 1900;
+                       if (tm.tm_mon > 0) {
+                               tm.tm_mon--;
+                               wpt->creation_time = mkgmtime(&tm);
+                       }
+               }
+               
+               track_add_wpt(trk, wpt);
+       }
+       xfree(buf);
+}
+
+static void
+ggv_log_wr_init(const char *fname)
+{
+       fout = gbfopen(fname, "wb", MYNAME);
+       
+       gbfputcstr("DOMGVGPS Logfile V1.0:", fout);
+}
+
+static void
+ggv_log_wr_deinit(void)
+{
+       gbfclose(fout);
+}
+
+static void
+ggv_log_track_head_cb(const route_head *trk)
+{
+       queue *elem, *tmp;
+       waypoint *prev = NULL;
+       
+       QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) {
+               double  latmin, lonmin, latsec, lonsec;
+               int     latint, lonint;
+               double  course = 0, speed = 0;
+               struct tm tm;
+               waypoint *wpt = (waypoint *)elem;
+               double secs = 0;
+               
+               latint = wpt->latitude;
+               lonint = wpt->longitude;
+               latmin = 60.0 * (fabs(wpt->latitude) - latint);
+               lonmin = 60.0 * (fabs(wpt->longitude) - lonint);
+               latsec = 60.0 * (latmin - floor(latmin));
+               lonsec = 60.0 * (lonmin - floor(lonmin));
+               
+               if (wpt->creation_time > 0) {
+                       tm = *gmtime(&wpt->creation_time);
+                       tm.tm_mon += 1;
+                       tm.tm_year += 1900;
+               }
+               else
+                       memset(&tm, 0, sizeof(tm));
+               
+               if (prev != NULL) {
+                       course = heading_true_degrees(
+                               prev->latitude, prev->longitude,
+                               wpt->latitude, wpt->longitude);
+                       speed = waypt_speed(prev, wpt);
+               }
+               if (wpt->creation_time > 0)
+                       secs = (double)tm.tm_sec + ((double)wpt->microseconds / 1000000);
+
+               gbfputint16((gbint16) latint, fout);
+               gbfputint16((gbint16) latmin, fout);
+               gbfputflt(latsec, fout);
+               gbfputint16((gbint16) lonint, fout);
+               gbfputint16((gbint16) lonmin, fout);
+               gbfputflt(lonsec, fout);
+               gbfputint16((gbint16) course, fout);
+               gbfputint16((gbint16) (wpt->altitude != unknown_alt) ? wpt->altitude : 0, fout);
+               gbfputint16((gbint16) speed, fout);
+               gbfputint16(0, fout);
+               gbfputint16(tm.tm_year, fout);
+               gbfputint16(tm.tm_mon, fout);
+               gbfputint16(tm.tm_mday, fout);
+               gbfputint16(tm.tm_hour, fout);
+               gbfputint16(tm.tm_min, fout);
+               gbfputdbl(secs, fout);
+               
+               prev = wpt;
+       }
+}
+
+static void
+ggv_log_write(void)
+{
+       track_disp_all(ggv_log_track_head_cb, NULL, NULL);
+}
+
+/**************************************************************************/
+
+ff_vecs_t ggv_log_vecs = {
+       ff_type_file,
+       { 
+               ff_cap_none,                    /* waypoints */
+               ff_cap_read | ff_cap_write,     /* tracks */
+               ff_cap_none                     /* routes */ 
+       },
+       ggv_log_rd_init,        
+       ggv_log_wr_init,
+       ggv_log_rd_deinit,      
+       ggv_log_wr_deinit,
+       ggv_log_read,
+       ggv_log_write,
+       NULL,
+       ggv_log_args,
+       CET_CHARSET_ASCII, 1
+};
+/**************************************************************************/
diff --git a/reference/track/ggv_log-sample.log b/reference/track/ggv_log-sample.log
new file mode 100644 (file)
index 0000000..9cbcba3
Binary files /dev/null and b/reference/track/ggv_log-sample.log differ
diff --git a/testo b/testo
index 0664aac86e12903b7b7cade0109dde06798f0c78..a79966f4a08151e302e539034592fb6288d9824f 100755 (executable)
--- a/testo
+++ b/testo
@@ -1201,4 +1201,13 @@ rm -f ${TMPDIR}/mlink*
 ${PNAME} -i gpx -f reference/multiple-links.gpx -o gpx,gpxver=1.1 -F ${TMPDIR}/mlink-1.gpx
 compare ${TMPDIR}/mlink-1.gpx reference/multiple-links.gpx
 
+#
+# Geogrid Viewer tracklogs
+#
+rm -f ${TMPDIR}/ggv_log*
+${PNAME} -i gdb -f ${REFERENCE}/gdb-sample.gdb -x track,pack -o ggv_log -F ${TMPDIR}/ggv_log-sample.log
+bincompare ${REFERENCE}/track/ggv_log-sample.log ${TMPDIR}/ggv_log-sample.log
+${PNAME} -i ggv_log -f ${REFERENCE}/track/ggv_log-sample.log -o ggv_log -F ${TMPDIR}/ggv_log-sample2.log
+bincompare ${REFERENCE}/track/ggv_log-sample.log ${TMPDIR}/ggv_log-sample2.log
+
 exit 0
diff --git a/vecs.c b/vecs.c
index 4d7aedc68c118ba563213f58ef1954c559b243fd..202d9669afa9085dc1a04f0c85a3b3ffe0e08b18 100644 (file)
--- a/vecs.c
+++ b/vecs.c
@@ -115,6 +115,7 @@ extern ff_vecs_t raymarine_vecs;
 extern ff_vecs_t alanwpr_vecs;
 extern ff_vecs_t alantrl_vecs;
 extern ff_vecs_t vitovtt_vecs;
+extern ff_vecs_t ggv_log_vecs;
 
 static
 vecs_t vec_list[] = {
@@ -637,6 +638,12 @@ vecs_t vec_list[] = {
                "Vito SmartMap tracks (.vtt)",
                "vtt"
         },
+        {
+                &ggv_log_vecs,
+                "ggv_log",
+                "Geogrid Viewer tracklogs (.log)",
+                "log"
+        },
        {
                NULL,
                NULL,